<template>
  <div>
    <a-spin tip="Loading..." :spinning="showSpinner">
      <a-input-search v-model:value="searchValue" style="margin-bottom: 8px" :placeholder="$t('common.Search')" />
      <a-tree v-if="categoryData.length" :expanded-keys="expandedKeys" :auto-expand-parent="autoExpandParent"
        :tree-data="categoryData" @expand="onExpand" block-node show-icon>
        <!-- 修改 title 插槽 -->
        <template #title="{ key, title, selected, children, remark, parentId, isNode }">
          <div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
            <!-- 标题内容 -->
            <div style="flex: 1; min-width: 0;">
              <span v-if="title.indexOf(searchValue) > -1">
                <FrownFilled v-if="selected" />
                <FrownOutlined v-else="selected" />
                {{ title.substring(0, title.indexOf(searchValue)) }}
                <span style="color: #f50">{{ searchValue }}</span>
                {{ title.substring(title.indexOf(searchValue) + searchValue.length) }}
              </span>
              <span v-else>
                <FrownFilled v-if="selected" />
                <FrownOutlined v-else="selected" />
                <span style="margin-left: 4px;">{{ title }}</span>
              </span>
            </div>

            <!-- 操作按钮 -->
            <!-- 删除，只能删除没有子节点的数据 -->
            <DeleteOutlined v-if="!children.length" @click.stop="nodeDel(key, title)" class="treeOperationBtn" />
            <!-- 添加 -->
            <PlusOutlined v-if="!isNode" @click.stop="nodeAdd(key, parentId)" style="margin-left: 10px;"
              class="treeOperationBtn" />
            <!-- 编辑 -->
            <EditOutlined @click.stop="nodeEdit(key, title, children, remark, parentId, isNode)" style="margin: 0 10px;"
              class="treeOperationBtn" />
          </div>
        </template>
      </a-tree>

      <a-modal v-model:open="editModel" :title="$t('common.edit')" @ok="handleEdit">
        <template #footer>
          <a-button class="cancelBtn" key="back" @click="editModel = false">{{ $t('common.cancel') }}</a-button>
          <a-button class="confirmBtn" key="submit" type="primary" :loading="loading" @click="handleEdit">{{
            $t('common.confirm') }}</a-button>
        </template>
        <a-form ref="formRef" :model="editAddRecord" :rules="rules">
          <a-form-item :label="$t('common.name')" name="name">
            <a-input v-model:value="editAddRecord.name" />
          </a-form-item>
          <a-form-item :label="$t('common.remark')" name="remark">
            <a-textarea v-model:value="editAddRecord.remark" />
          </a-form-item>
          <a-form-item :label="$t('common.ChildNode')" name="isNode">
            <a-radio-group v-model:value="editAddRecord.isNode" name="radioGroup">
              <a-radio :value="1">{{ $t('common.yes') }}</a-radio>
              <a-radio :value="0">{{ $t('common.no') }}</a-radio>
            </a-radio-group>
          </a-form-item>
        </a-form>
      </a-modal>

      <a-modal v-model:open="addModel" :title="$t('common.add')" @ok="handleAdd">
        <template #footer>
          <a-button class="cancelBtn" key="back" @click="addModel = false">{{ $t('common.cancel') }}</a-button>
          <a-button class="confirmBtn" key="submit" type="primary" :loading="loading" @click="handleAdd">{{
            $t('common.confirm') }}</a-button>
        </template>
        <a-form ref="formRef" :model="editAddRecord" :rules="rules">
          <a-form-item label="名称" name="name">
            <a-input v-model:value="editAddRecord.name" />
          </a-form-item>
          <a-form-item :label="$t('common.remark')" name="remark">
            <a-textarea v-model:value="editAddRecord.remark" />
          </a-form-item>
          <a-form-item label="子节点" name="isNode">
            <a-radio-group v-model:value="editAddRecord.isNode">
              <a-radio :value="1">{{ $t('common.yes') }}</a-radio>
              <a-radio :value="0">{{ $t('common.no') }}</a-radio>
            </a-radio-group>
          </a-form-item>
        </a-form>
      </a-modal>
    </a-spin>
  </div>
</template>
<script setup>
import { addCategory, deleteCategory, editCategory, findList } from '@/api/ingredientCategory.js';
import { ExclamationCircleOutlined, FrownFilled, FrownOutlined } from '@ant-design/icons-vue';
import { Modal, message } from 'ant-design-vue';
import { createVNode, onMounted, reactive, ref, watch } from 'vue';
// 树-数据
const categoryData = ref([]);
// 扁平化数据 [{key:节点id, title: 节点名称}]
const dataList = ref([]);
// 需要展开的父节点列表
const expandedKeys = ref([]);
// 搜索内容
const searchValue = ref('');
// 是否自动展开expandedKeys中的父节点
const autoExpandParent = ref(true);
// 编辑数据
const editAddRecord = reactive({
  id: '',
  parentId: '',
  name: '',
  remark: '',
  isNode: 1,
});
// 加载数据框
const showSpinner = ref(false);
// 加载
const loading = ref(false);
// 编辑框展示
const editModel = ref(false);
// 添加框展示
const addModel = ref(false);
// 规则校验
const rules = {
  name: [
    {
      required: true,
      message: '请输入分类名称',
      trigger: 'change',
    },
  ],
  isNode: [
    {
      required: true,
      message: '请输入分类名称',
      trigger: 'change',
    },
  ],

};


onMounted(async () => {
  showSpinner.value = true;
  await getCategoryData();
  expandedKeys.value = dataList.value.filter(e => e.isNode === 0).map(e => e.key);
  showSpinner.value = false;
})
// 获取树节点数据
const getCategoryData = async () => {
  await findList().then(res => {
    if (res.code === 200) {
      console.log(res.data);
      categoryData.value = res.data;
      // 生成扁平数据
      generateList(res.data);

    }
  })
}

// 生成扁平数据列表（用于搜索时查找父节点）
const generateList = data => {
  for (let i = 0; i < data.length; i++) {
    const node = data[i];
    const key = node.key;
    dataList.value.push({
      key,
      title: node.title,
      isNode: node.isNode,
    });
    if (node.children) {
      generateList(node.children);
    }
  }
};
// 获取父级key
const getParentKey = (key, tree) => {
  let parentKey;
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.children) {
      if (node.children.some(item => item.key === key)) {
        parentKey = node.key;
      } else if (getParentKey(key, node.children)) {
        parentKey = getParentKey(key, node.children);
      }
    }
  }
  return parentKey;
};
// 	展开/收起节点时触发
const onExpand = keys => {
  console.log("keys:");
  console.log(keys);
  expandedKeys.value = keys;
  autoExpandParent.value = true;
};

// 监听searchValue
watch(searchValue, value => {
  const expanded = dataList.value
    .map(item => {
      if (item.title.indexOf(value) > -1) {
        return getParentKey(item.key, categoryData.value);
      }
      return null;
    })
    .filter((item, i, self) => item && self.indexOf(item) === i);
  expandedKeys.value = expanded;
  searchValue.value = value;
  autoExpandParent.value = true;
});

// 展示编辑页面
const nodeEdit = (key, title, children, remark, parentId, isNode) => {
  editAddRecord.id = key;
  editAddRecord.name = title;
  editAddRecord.remark = remark;
  editAddRecord.parentId = parentId;
  editAddRecord.isNode = isNode;
  editModel.value = true;
  console.log(editAddRecord);
}
// 编辑节点
const handleEdit = () => {
  if (!editAddRecord.id) {
    message.error('主键不能为空');
  }
  editCategory(editAddRecord).then(res => {
    if (res.code === 200) {
      message.success('编辑成功');
      getCategoryData();
      editModel.value = false;
    }
  })
}
// 新增节点
const handleAdd = () => {
  console.log(editAddRecord);
  addCategory(editAddRecord).then(res => {
    if (res.code === 200) {
      message.success('添加成功');
      getCategoryData();
      addModel.value = false;
    }
  })
}

// 确认删除弹框
const nodeDel = (id, title) => {
  Modal.confirm({
    title: '系统消息',
    icon: createVNode(ExclamationCircleOutlined),
    content: `确定要删除(${title})节点吗?`,
    okText: '是',
    okType: 'danger',
    cancelText: '否',
    onOk() {
      deleteCategory(id).then(res => {
        if (res.code === 200) {
          message.success('删除成功');
          getCategoryData();
        }
      });
    },
    onCancel() {
    },
  });
}

const nodeAdd = (id, parentId) => {
  addModel.value = true;
  editAddRecord.isNode = 1;
  editAddRecord.id = null;
  editAddRecord.name = null;
  editAddRecord.remark = null;
  editAddRecord.parentId = id;
}
</script>

<style scoped lang="scss">
.wrap {
  position: relative;
  width: 350px;
  background: #fff;
}

.ant-tree li span.ant-tree-iconEle {
  width: 14px;
  height: 14px;
  position: absolute;
  right: 70px;

  .plusType,
  .editType,
  .deleteType {
    &:hover {
      color: green;
    }
  }
}

.treeOperationBtn:hover {
  color: green !important;
}
</style>
